package com.example.testdemo.db;

import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import androidx.annotation.Nullable;

import com.example.testdemo.MainActivity;
import com.example.testdemo.annotation.Table;
import com.example.testdemo.db.reflex.Reflex;
import com.example.testdemo.db.sql.SqlPare;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *
 * </p>
 *
 * @author 永健
 * @since 2020-03-27 17:27
 */
public abstract class BaseDao<T> extends BaseDb<T> {

    protected static final int DATABASE_VERSION = 1;

    private String tableName;
    private Class<T> tClass;


    public BaseDao() throws Exception {
        super("test.db", DATABASE_VERSION);
        paraTableName();
    }

    private void paraTableName() throws Exception {
        Class<?> aClass = getTClass();
        Table table = aClass.getAnnotation(Table.class);
        if (table == null) {
            throw new Exception("构造出错,请在实体类中添加注解 @Table");
        }
        this.tableName = table.name();
    }

    private Class<T> getTClass() {
        Class<T> tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        this.tClass = tClass;
        return tClass;
    }

    private ContentValues trans(Map<String, Object> map) {
        ContentValues contentValues = new ContentValues();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Object value = entry.getValue();
            if (value != null) {
                if (value instanceof Integer) {
                    contentValues.put(entry.getKey(), ((Integer) value).intValue());

                } else if (value instanceof Long) {
                    contentValues.put(entry.getKey(), ((Long) value).longValue());

                } else if (value instanceof String) {
                    contentValues.put(entry.getKey(), (value).toString());

                } else if (value instanceof Double) {
                    contentValues.put(entry.getKey(), ((Double) value).doubleValue());

                } else if (value instanceof Float) {
                    contentValues.put(entry.getKey(), ((Float) value).floatValue());
                } else if (value instanceof Boolean) {
                    contentValues.put(entry.getKey(), ((Boolean) value).booleanValue());
                } else if (value instanceof byte[]) {
                    contentValues.put(entry.getKey(), (byte[]) value);
                } else if (value instanceof Byte) {
                    contentValues.put(entry.getKey(), ((Byte) value).byteValue());
                } else if (value instanceof Date) {
                    Date date = (Date) value;
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    contentValues.put(entry.getKey(), simpleDateFormat.format(date));
                }
            }
        }
        return contentValues;
    }


    /**
     * 插入一条记录
     *
     * @param entity 实体对象
     */
    public long insert(T entity) {
        Map<String, Object> keyValues = Reflex.getKeyValues(entity);
        return insert(tableName, trans(keyValues));
    }

    /**
     * 根据 ID 修改
     *
     * @param entity 实体对象
     */
    public long updateById(T entity) {
        long raw = 1;
        try {
            String byIdSql = new SqlPare<T>(tClass).updateByIdSql(entity);
            execute(byIdSql);
        } catch (Exception e) {
            e.printStackTrace();
            raw = 0;
        }
        return raw;
    }


    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    public T selectById(Serializable id) {
        try {
            SqlPare<T> tSqlPare = new SqlPare<>(tClass);
            List<T> query = query(tSqlPare.selectByIdSql(), new String[]{String.valueOf(id)});
            return query.isEmpty() ? null : query.get(0);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据 entity 条件，查询全部记录
     */
    public List<T> selectListAll() {
        List<T> list = new ArrayList<>();
        try {
            SqlPare<T> tSqlPare = new SqlPare<>(tClass);
            list = query(tSqlPare.selectAllSql(), null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    public List<Map<String, Object>> selectListAllMap() {
        List<Map<String, Object>> maps = new ArrayList<>();
        try {
            SqlPare<T> tSqlPare = new SqlPare<>(tClass);
            maps = queryMap(tSqlPare.selectAllSql(), null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return maps;
    }


    /**
     * 根据 ID 删除
     *
     * @param id 主键ID
     */
    public int deleteById(Serializable id) {
        int row = 1;
        try {
            SqlPare<T> tSqlPare = new SqlPare<>(tClass);
            execute(tSqlPare.deleteByIdSql(id));
        } catch (Exception e) {
            e.printStackTrace();
            row = 0;
        }
        return row;
    }

    /**
     * 清空数据库
     *
     * @return
     */
    public boolean deleteAll() {
        boolean flag = true;
        try {
            SqlPare<T> tSqlPare = new SqlPare<>(tClass);
            execute(tSqlPare.deleteAll());
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }


}
